home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 9 / CDACTUAL9.iso / share / Dos / VARIOS / pascal / INTERRUP.SWG / 0001_Interrupt driven external events.pas
Encoding:
Pascal/Delphi Source File  |  1996-02-21  |  4.6 KB  |  133 lines

  1. { This little program shows how to count or act on external events. It works
  2.   since 3 years in a industial application without any problems.
  3.   It's interrupt driven to make sure, that no event is missed.
  4.  
  5.   You need a male DB25 connector (the counterpart of the PC's printer
  6.   connector), and at least 2 wires. A switch is recommend.
  7.   What you have to do is to connect 2 wires to the male DB25 connector.
  8.   One wire to pin 10 and the other to pin 25.
  9.  
  10.               IRQ-inputline
  11.             +----------------+
  12.             |                |
  13.             -         13     |10               1
  14.           switch       - - - - - - - - - - - - -
  15.             -           - - - - - - - - - - - -   backview of connector
  16.             |         25|                     14
  17.             +-----------+
  18.                ground
  19.  
  20.   Pin 10 is the acknowledge line (input) witch normaly is connected to a
  21.   printer output signal. A internal resistor with 4,7k_ pulls this pin up to
  22.   5V TTL level. So the normal level is 5V TTL. With some software setup
  23.   this input line can perform interrupts when the signal is forced from high
  24.   to low level. This can be done with a simple switch that connects pin10 to
  25.   ground. The little "framework" above shows it.
  26.  
  27.   In the program below events up to 35kHz can be sensed.
  28.  
  29.   Try ($define IRQ7) first. If this doesn't work then use ($define IRQ5).
  30.   If you do your own interrupt service, consider that it must be a far proc.
  31.  
  32.   There's a lot of what you can do with this - go external...
  33.  
  34.   Dec. 12, 1995, Udo Juerss, 57078 Siegen, Germany, CompuServe [101364,526]}
  35.  
  36. {$define IRQ7}
  37. uses
  38.   Dos,
  39.   Crt;
  40. {---------------------------------------------------------------------------}
  41.  
  42. var
  43.   Lpt            : Word;
  44.   InterruptCount : Word;
  45.   LptOrgVec      : Procedure;
  46. {---------------------------------------------------------------------------}
  47.  
  48. procedure SetPortBit(PortAdr:Word; Bit:Byte); assembler;
  49. asm
  50.            mov   dx,PortAdr
  51.            in    al,dx
  52.            mov   cl,Bit
  53.            and   cl,7
  54.            mov   ah,1
  55.            shl   ah,cl
  56.            or    al,ah
  57.            out   dx,al
  58. end;
  59. {---------------------------------------------------------------------------}
  60.  
  61. procedure ClearPortBit(PortAdr:Word; Bit:Byte); assembler;
  62. asm
  63.            mov   dx,PortAdr
  64.            in    al,dx
  65.            mov   cl,Bit
  66.            and   cl,7
  67.            mov   ah,1
  68.            shl   ah,cl
  69.            not   ah
  70.            and   al,ah
  71.            out   dx,al
  72. end;
  73. {---------------------------------------------------------------------------}
  74.  
  75. function GetLptPort(LptNr:Byte):Word;
  76. begin
  77.   GetLptPort:=MemW[$0040:8 + (LptNr - 1) * 2];
  78. end;
  79. {---------------------------------------------------------------------------}
  80.  
  81. {$F+}
  82. procedure NewLptInt; interrupt;
  83. begin
  84.   Sound(880);                                      {Quittungssignal ausgeben}
  85.   Delay(5);
  86.   NoSound;
  87.  
  88.   Inc(InterruptCount);                              {Interruptzdhler erhvhen}
  89.  
  90.   SetPortBit(Lpt + 1,6);                 {Bit 6 im Interrupt Register setzen}
  91.  
  92.   asm                                         {Interrupt Anforderung lvschen}
  93.     mov  al,20h
  94.     out  20h,al
  95.   end;
  96. end;
  97. {$F-}
  98. {---------------------------------------------------------------------------}
  99.  
  100. begin
  101.   ClrScr;
  102.  
  103.   Lpt:=GetLptPort(1);                     {Port Adresse der 1. Schnittstelle}
  104.   SetPortBit(Lpt + 1,6);                 {Bit 6 im Interrupt Register setzen}
  105.   SetPortBit(Lpt + 2,4);                  {Bit 4 im Kontroll Register setzen}
  106.  
  107. {$ifdef IRQ7}
  108.   ClearPortBit($21,7);                {IRQ7 im Intrrupt-Controller freigeben}
  109.   GetIntVec($0F,@LptOrgVec);              {Bisherigen Interrupt Vektor holen}
  110.   SetIntVec($0F,@NewLptInt);              {Vektor f|r neuen Interrupt setzen}
  111. {$else}
  112.   ClearPortBit($21,5);                {IRQ5 im Intrrupt-Controller freigeben}
  113.   GetIntVec($0D,@LptOrgVec);              {Bisherigen Interrupt Vektor holen}
  114.   SetIntVec($0D,@NewLptInt);              {Vektor f|r neuen Interrupt setzen}
  115. {$endif}
  116.  
  117.   Writeln('Press the interrupt-switch to test response, or any key to quit...');
  118.   Writeln('Interrupts occurrences : ');
  119.   InterruptCount:=0;
  120.   repeat
  121.     GotoXY(25,2);
  122.     Write(InterruptCount:5);
  123.   until KeyPressed;
  124.   ReadKey;
  125.  
  126. {$ifdef IRQ7}
  127.   SetPortBit($21,7);                    {IRQ7 im Intrrupt-Controller sperren}
  128.   SetIntVec($0F,@LptOrgVec);     {Vektor von urspr|nglichem Interrupt setzen}
  129. {$else}
  130.   SetPortBit($21,5);                    {IRQ5 im Intrrupt-Controller sperren}
  131.   SetIntVec($0D,@LptOrgVec);     {Vektor von urspr|nglichem Interrupt setzen}
  132. {$endif}
  133. end.